#library
library(sf)
## Linking to GEOS 3.11.0, GDAL 3.5.3, PROJ 9.1.0; sf_use_s2() is TRUE
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.1 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(tmap)
## Breaking News: tmap 3.x is retiring. Please test v4, e.g. with
## remotes::install_github('r-tmap/tmap')
library(tmaptools)
library(here)
## here() starts at /Users/tsernian/Documents/CASA/CASA0005_GIS and Science/CASA0005_GIS and Science
library(grid)
library(leafpop)
library(leaflet)
#load data
londonboundry <- st_read(here::here("/Users/tsernian/Documents/CASA/CASA0005_GIS and Science/CASA0005_GIS and Science/week5/data/statistical-gis-boundaries-london/ESRI/London_Borough_Excluding_MHW.shp")) %>%
st_transform(., 27700)
## Reading layer `London_Borough_Excluding_MHW' from data source
## `/Users/tsernian/Documents/CASA/CASA0005_GIS and Science/CASA0005_GIS and Science/week5/data/statistical-gis-boundaries-london/ESRI/London_Borough_Excluding_MHW.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 33 features and 7 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 503568.2 ymin: 155850.8 xmax: 561957.5 ymax: 200933.9
## Projected CRS: OSGB36 / British National Grid
osm <- st_read(here::here("/Users/tsernian/Documents/CASA/CASA0005_GIS and Science/CASA0005_GIS and Science/week5/data/greater-london-latest-free.shp/gis_osm_pois_a_free_1.shp")) %>%
st_transform(., 27700) %>%
dplyr::filter(fclass == 'hotel')
## Reading layer `gis_osm_pois_a_free_1' from data source
## `/Users/tsernian/Documents/CASA/CASA0005_GIS and Science/CASA0005_GIS and Science/week5/data/greater-london-latest-free.shp/gis_osm_pois_a_free_1.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 48376 features and 4 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -0.5108706 ymin: 51.28109 xmax: 0.322123 ymax: 51.6926
## Geodetic CRS: WGS 84
worldcities <- st_read(here::here("/Users/tsernian/Documents/CASA/CASA0005_GIS and Science/CASA0005_GIS and Science/week5/data/World_Cities.shp/World_Cities.shp")) %>%
st_transform(., 27700)
## Reading layer `World_Cities' from data source
## `/Users/tsernian/Documents/CASA/CASA0005_GIS and Science/CASA0005_GIS and Science/week5/data/World_Cities.shp/World_Cities.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 2540 features and 14 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: -19609100 ymin: -7321602 xmax: 19950890 ymax: 14476660
## Projected CRS: WGS 84 / Pseudo-Mercator
ukoutline <- st_read(here::here("/Users/tsernian/Documents/CASA/CASA0005_GIS and Science/CASA0005_GIS and Science/week5/data/gadm41_GBR_shp/gadm41_GBR_0.shp")) %>%
st_transform(., 27700)
## Reading layer `gadm41_GBR_0' from data source
## `/Users/tsernian/Documents/CASA/CASA0005_GIS and Science/CASA0005_GIS and Science/week5/data/gadm41_GBR_shp/gadm41_GBR_0.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 1 feature and 2 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -8.649996 ymin: 49.86531 xmax: 1.764393 ymax: 60.84548
## Geodetic CRS: WGS 84
airbnb <- read_csv("/Users/tsernian/Documents/CASA/CASA0005_GIS and Science/CASA0005_GIS and Science/week5/data/listings.csv") %>%
st_as_sf(., coords = c("longitude", "latitude"),
crs = 4326) %>%
st_transform(., 27700)%>%
#select entire places that are available all year
filter(room_type == 'Entire home/apt' & availability_365 =='365')
## Rows: 96182 Columns: 18
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (4): name, host_name, neighbourhood, room_type
## dbl (11): id, host_id, latitude, longitude, price, minimum_nights, number_o...
## lgl (2): neighbourhood_group, license
## date (1): last_review
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(airbnb)
## Simple feature collection with 6 features and 16 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: 515861.3 ymin: 168804.4 xmax: 534526.8 ymax: 197843.8
## Projected CRS: OSGB36 / British National Grid
## # A tibble: 6 × 17
## id name host_id host_name neighbourhood_group neighbourhood room_type
## <dbl> <chr> <dbl> <chr> <lgl> <chr> <chr>
## 1 170524 STUNNING… 194769 D NA Westminster Entire h…
## 2 178519 Newly re… 1954110 Tariq NA Brent Entire h…
## 3 229335 SALE-5 m… 1197888 Louise NA Westminster Entire h…
## 4 81080 Luxury S… 439154 Lucy NA Richmond upo… Entire h…
## 5 316864 Trendy L… 1626989 Shimmy NA Enfield Entire h…
## 6 325809 Big Hous… 1666422 Stephen NA Camden Entire h…
## # ℹ 10 more variables: price <dbl>, minimum_nights <dbl>,
## # number_of_reviews <dbl>, last_review <date>, reviews_per_month <dbl>,
## # calculated_host_listings_count <dbl>, availability_365 <dbl>,
## # number_of_reviews_ltm <dbl>, license <lgl>, geometry <POINT [m]>
#spatial data join function
Joinfun1 <- function(data1, data2){
output<- data1%>%
st_join(data2,.) %>%
add_count(GSS_CODE, name="hotels_in_borough")
return(output)
}
hotels <- Joinfun1(osm, londonboundry)
airbnb2 <- Joinfun1(airbnb, londonboundry)
head(hotels)
## Simple feature collection with 6 features and 12 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 516362.6 ymin: 159907.4 xmax: 522654 ymax: 172367
## Projected CRS: OSGB36 / British National Grid
## NAME GSS_CODE HECTARES NONLD_AREA ONS_INNER SUB_2009
## 1 Kingston upon Thames E09000021 3726.117 0 F <NA>
## 2 Kingston upon Thames E09000021 3726.117 0 F <NA>
## 3 Kingston upon Thames E09000021 3726.117 0 F <NA>
## 4 Kingston upon Thames E09000021 3726.117 0 F <NA>
## 5 Kingston upon Thames E09000021 3726.117 0 F <NA>
## 6 Kingston upon Thames E09000021 3726.117 0 F <NA>
## SUB_2006 osm_id code fclass name
## 1 <NA> 28055159 2401 hotel Premier Inn
## 2 <NA> 161631526 2401 hotel Chessington Safari Hotel
## 3 <NA> 421483573 2401 hotel Premier Inn Chessington
## 4 <NA> 421506999 2401 hotel Chessington Azteca Hotel
## 5 <NA> 502772206 2401 hotel Warren House
## 6 <NA> 893668667 2401 hotel DoubleTree by Hilton Kingston Upon Thames
## hotels_in_borough geometry
## 1 6 MULTIPOLYGON (((516401.6 16...
## 2 6 MULTIPOLYGON (((516401.6 16...
## 3 6 MULTIPOLYGON (((516401.6 16...
## 4 6 MULTIPOLYGON (((516401.6 16...
## 5 6 MULTIPOLYGON (((516401.6 16...
## 6 6 MULTIPOLYGON (((516401.6 16...
head(airbnb2)
## Simple feature collection with 6 features and 24 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 516362.6 ymin: 159907.4 xmax: 522654 ymax: 172367
## Projected CRS: OSGB36 / British National Grid
## NAME GSS_CODE HECTARES NONLD_AREA ONS_INNER SUB_2009
## 1 Kingston upon Thames E09000021 3726.117 0 F <NA>
## 2 Kingston upon Thames E09000021 3726.117 0 F <NA>
## 3 Kingston upon Thames E09000021 3726.117 0 F <NA>
## 4 Kingston upon Thames E09000021 3726.117 0 F <NA>
## 5 Kingston upon Thames E09000021 3726.117 0 F <NA>
## 6 Kingston upon Thames E09000021 3726.117 0 F <NA>
## SUB_2006 id name
## 1 <NA> 2.119582e+07 "Studio twenty-eight" en-suite+kitchenette
## 2 <NA> 6.868230e+17 Lovely 3 bedroom flat in Kingston
## 3 <NA> 8.026361e+17 A Garden Bungalow in Kingston
## 4 <NA> 1.064465e+18 Fire station conversion
## 5 <NA> 1.121452e+18 Studio/Sleeps3/Netflix+Parking+Shopping+FreeSnacks
## 6 <NA> 1.193244e+18 stunning 1bedroom flat
## host_id host_name neighbourhood_group neighbourhood
## 1 153085636 Edgar And Helena NA Kingston upon Thames
## 2 473462502 Constantin NA Kingston upon Thames
## 3 189437187 Hua NA Kingston upon Thames
## 4 75035308 Ella NA Kingston upon Thames
## 5 562847587 Saffron NA Kingston upon Thames
## 6 4679034 Michael NA Kingston upon Thames
## room_type price minimum_nights number_of_reviews last_review
## 1 Entire home/apt 75 5 102 2024-07-27
## 2 Entire home/apt 170 90 0 <NA>
## 3 Entire home/apt 72 5 5 2024-06-15
## 4 Entire home/apt 175 2 5 2024-08-25
## 5 Entire home/apt 119 2 7 2024-07-27
## 6 Entire home/apt 250 1 0 <NA>
## reviews_per_month calculated_host_listings_count availability_365
## 1 1.21 5 365
## 2 NA 3 365
## 3 0.29 1 365
## 4 1.95 1 365
## 5 1.74 3 365
## 6 NA 1 365
## number_of_reviews_ltm license hotels_in_borough
## 1 4 NA 8
## 2 0 NA 8
## 3 2 NA 8
## 4 5 NA 8
## 5 7 NA 8
## 6 0 NA 8
## geometry
## 1 MULTIPOLYGON (((516401.6 16...
## 2 MULTIPOLYGON (((516401.6 16...
## 3 MULTIPOLYGON (((516401.6 16...
## 4 MULTIPOLYGON (((516401.6 16...
## 5 MULTIPOLYGON (((516401.6 16...
## 6 MULTIPOLYGON (((516401.6 16...
#count how many hotels and airbnb in the london polygon
hotels <- hotels %>%
group_by(., GSS_CODE, NAME)%>%
summarise(`Accomodation count` = unique(hotels_in_borough))
## `summarise()` has grouped output by 'GSS_CODE'. You can override using the
## `.groups` argument.
head(hotels)
## Simple feature collection with 6 features and 3 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 515484.9 ymin: 156480.9 xmax: 554089.2 ymax: 198355.2
## Projected CRS: OSGB36 / British National Grid
## # A tibble: 6 × 4
## # Groups: GSS_CODE [6]
## GSS_CODE NAME `Accomodation count` geometry
## <chr> <chr> <int> <MULTIPOLYGON [m]>
## 1 E09000001 City of London 23 (((531145.1 180782.1, 531…
## 2 E09000002 Barking and Dagenham 9 (((543905.4 183199.1, 543…
## 3 E09000003 Barnet 14 (((524579.9 198355.2, 524…
## 4 E09000004 Bexley 6 (((547226.2 181299.3, 547…
## 5 E09000005 Brent 13 (((525201 182512.6, 52518…
## 6 E09000006 Bromley 4 (((540373.6 157530.4, 540…
airbnb2 <- airbnb2 %>%
group_by(., GSS_CODE, NAME)%>%
summarise(`Accomodation count` = unique(hotels_in_borough))
## `summarise()` has grouped output by 'GSS_CODE'. You can override using the
## `.groups` argument.
head(airbnb2)
## Simple feature collection with 6 features and 3 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 515484.9 ymin: 156480.9 xmax: 554089.2 ymax: 198355.2
## Projected CRS: OSGB36 / British National Grid
## # A tibble: 6 × 4
## # Groups: GSS_CODE [6]
## GSS_CODE NAME `Accomodation count` geometry
## <chr> <chr> <int> <MULTIPOLYGON [m]>
## 1 E09000001 City of London 14 (((531145.1 180782.1, 531…
## 2 E09000002 Barking and Dagenham 35 (((543905.4 183199.1, 543…
## 3 E09000003 Barnet 53 (((524579.9 198355.2, 524…
## 4 E09000004 Bexley 22 (((547226.2 181299.3, 547…
## 5 E09000005 Brent 40 (((525201 182512.6, 52518…
## 6 E09000006 Bromley 41 (((540373.6 157530.4, 540…
tmap_mode("plot")
## tmap mode set to plotting
# set the breaks
# for our mapped data
breaks = c(0, 5, 12, 26, 57, 286)
# plot each map
tm1 <- tm_shape(hotels) +
tm_polygons("Accomodation count",
breaks=breaks,
palette="PuBu")+
tm_legend(show=FALSE)+
tm_layout(frame=FALSE)+
tm_credits("(a)", position=c(0,0.85), size=1.5)
tm2 <- tm_shape(airbnb2) +
tm_polygons("Accomodation count",
breaks=breaks,
palette="PuBu") +
tm_legend(show=FALSE)+
tm_layout(frame=FALSE)+
tm_credits("(b)", position=c(0,0.85), size=1.5)
legend <- tm_shape(hotels) +
tm_polygons("Accomodation count",
breaks=breaks,
palette="PuBu") +
tm_scale_bar(position=c(0.2,0.04), text.size=0.6)+
tm_compass(north=0, position=c(0.65,0.6))+
tm_layout(legend.only = TRUE, legend.position=c(0.2,0.25),asp=0.1)+
tm_credits("(c) OpenStreetMap contrbutors and Air b n b", position=c(0.0,0.0))
worldcities2 <- worldcities %>%
filter(CNTRY_NAME=='United Kingdom'&
worldcities$CITY_NAME=='Birmingham'|
worldcities$CITY_NAME=='London'|
worldcities$CITY_NAME=='Edinburgh')
newbb <- c(xmin=-296000, ymin=5408, xmax=655696, ymax=1000000)
ukoutlinecrop <- ukoutline$geometry %>%
st_crop(., newbb)
tm3 <- tm_shape(ukoutlinecrop)+
tm_polygons(col="darkslategray1")+
tm_layout(frame=FALSE)+
tm_shape(worldcities2) +
tm_symbols(col = "red", scale = .5)+
tm_text("CITY_NAME", xmod=-1, ymod=-0.5)
#library(grid)
# erases the current device or moves to a new page
# probably not needed but makes sure you are plotting on a new page.
grid.newpage()
pushViewport(viewport(layout=grid.layout(2,2)))
print(tm1, vp=viewport(layout.pos.col=1, layout.pos.row=1, height=5))
## Warning: Values have found that are higher than the highest break
print(tm2, vp=viewport(layout.pos.col=2, layout.pos.row=1, height=5))
print(tm3, vp=viewport(layout.pos.col=1, layout.pos.row=2, height=5))
print(legend, vp=viewport(layout.pos.col=2, layout.pos.row=2, height=5))
## Warning: Values have found that are higher than the highest break

tmap_mode("view")
## tmap mode set to interactive viewing
tm_shape(airbnb2) +
tm_polygons("Accomodation count", breaks=breaks)
# library for pop up boxes
#library(leafpop)
#library(leaflet)
#join data
Joined <- airbnb2%>%
st_join(., hotels, join = st_equals)%>%
dplyr::select(GSS_CODE.x, NAME.x, `Accomodation count.x`, `Accomodation count.y`)%>%
dplyr::rename(`GSS code` =`GSS_CODE.x`,
`Borough` = `NAME.x`,
`Airbnb count` = `Accomodation count.x`,
`Hotel count`= `Accomodation count.y`)%>%
st_transform(., 4326)
#remove the geometry for our pop up boxes to avoid
popupairbnb <-Joined %>%
st_drop_geometry()%>%
dplyr::select(`Airbnb count`, Borough)%>%
popupTable()
## Adding missing grouping variables: `GSS code`
popuphotel <-Joined %>%
st_drop_geometry()%>%
dplyr::select(`Hotel count`, Borough)%>%
popupTable()
## Adding missing grouping variables: `GSS code`
tmap_mode("view")
## tmap mode set to interactive viewing
# set the colour palettes using our previously defined breaks
pal1 <- Joined %>%
colorBin(palette = "YlOrRd", domain=.$`Airbnb count`, bins=breaks)
pal1 <-colorBin(palette = "YlOrRd", domain=Joined$`Airbnb count`, bins=breaks)
pal2 <- Joined %>%
colorBin(palette = "YlOrRd", domain=.$`Hotel count`, bins=breaks)
map<- leaflet(Joined) %>%
#add our polygons, linking to the tables we just made
addPolygons(color="white",
weight = 2,
opacity = 1,
dashArray = "3",
popup = popupairbnb,
fillOpacity = 0.7,
fillColor = ~pal2(`Airbnb count`),
group = "Airbnb")%>%
addPolygons(fillColor = ~pal2(`Hotel count`),
weight = 2,
opacity = 1,
color = "white",
dashArray = "3",
popup = popupairbnb,
fillOpacity = 0.7,group = "Hotels")%>%
#add basemaps
addTiles(group = "OSM (default)") %>%
addProviderTiles(providers$Stadia.StamenToner, group = "Toner") %>%
addProviderTiles(providers$Stadia.StamenTonerLite, group = "Toner Lite") %>%
addProviderTiles(providers$CartoDB.Positron, group = "CartoDB")%>%
# add a legend
addLegend(pal = pal2, values = ~`Hotel count`, group = c("Airbnb","Hotel"),
position ="bottomleft", title = "Accomodation count") %>%
# specify layers control
addLayersControl(
baseGroups = c("OSM (default)", "Toner", "Toner Lite", "CartoDB"),
overlayGroups = c("Airbnb", "Hotels"),
options = layersControlOptions(collapsed = FALSE)
)
## Warning in pal2(`Hotel count`): Some values were outside the color scale and
## will be treated as NA
# plot the map
map